package com.my.kindlesend.interceptor;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.my.kindlesend.dao.UserInfoDao;
import com.my.kindlesend.entity.UserInfo;
import com.my.kindlesend.result.Result;
import com.my.kindlesend.utils.UserThreadLocal;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;
import java.util.Optional;

/**
 * 微信登录拦截器
 * 拦截所有以/wx开头的请求，除了/wx/login
 * 通过请求头中的openId查询用户信息并存储到ThreadLocal中
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class WxLoginInterceptor implements HandlerInterceptor {

    private final UserInfoDao userInfoDao;
    private final ObjectMapper objectMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();

        // 允许/wx/login请求通过，不需要验证openId
        if ("/wx/login".equals(requestURI)) {
            return true;
        }

        // 检查是否是以/wx开头的请求
        if (requestURI.startsWith("/wx/")) {
            // 从请求头中获取openId
            String openId = Optional.ofNullable(request.getHeader("openId")).orElse(request.getHeader("openid"));
            if (StrUtil.isBlank(openId)) {
                // 如果没有openId，返回未登录错误
                sendErrorResponse(response, "未提供openId，无法验证登录状态");
                return false;
            }

            // 通过openId查询用户信息
            Optional<UserInfo> userInfoOptional = userInfoDao.findByOpenId(openId);
            if (userInfoOptional.isEmpty()) {
                // 如果用户不存在，返回未登录错误
                sendErrorResponse(response, "未找到用户信息，请先登录");
                return false;
            }

            // 将用户信息存入ThreadLocal
            UserInfo userInfo = userInfoOptional.get();
            UserThreadLocal.set(userInfo);
            log.info("用户[{}]登录验证通过，请求URI: {}", userInfo.getNickName(), requestURI);
        }

        return true;
    }

    /**
     * 向前端发送错误响应
     * @param response HTTP响应对象
     * @param errorMessage 错误消息
     * @throws Exception 异常信息
     */
    private void sendErrorResponse(HttpServletResponse response, String errorMessage) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.setHeader("Content-Type", "application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.write(objectMapper.writeValueAsString(Result.error(errorMessage)));
        writer.flush();
        writer.close();
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理ThreadLocal，防止内存泄漏
        UserThreadLocal.remove();
        log.debug("ThreadLocal已清理，请求URI: {}", request.getRequestURI());
    }
}